%%%-------------------------------------------------------------------
%%% @author liuwentao
%%% @doc
%%%
%%% @end
%%% Created : 24. 5月 2021 11:15
%%%-------------------------------------------------------------------
-module(server_mgr).
-author("liuwentao").

-behaviour(gen_server).


%% 进程接口
-export([
    start_link/1        %% 进程开启函数
]).


%% gen_server callbacks
-export([init/1, handle_call/3, handle_cast/2, handle_info/2, terminate/2, code_change/3]).

-define(SERVER, ?MODULE).

-record(state, {}).

-include("common.hrl").
-include("service.hrl").


%%%===================================================================
%%% API
%%%===================================================================
%% @doc 进程启动
-spec(start_link(Type :: atom()) ->
    {ok, Pid :: pid()} | ignore | {error, Reason :: term()}).
start_link(Type) ->
    gen_server:start_link({local, ?SERVER}, ?MODULE, [Type], []).

%%%===================================================================
%%% gen_server callbacks
%%%===================================================================
init([Type]) ->
    self() ! {init, Type},
    {ok, #state{}}.


%% 执行同步apply操作
handle_call(_Request, _From, State) ->
    {reply, ok, State}.

handle_cast(_Request, State) ->
    {noreply, State}.


%% 执行异步apply操作
handle_info({init, Type}, State) ->
    Result =
    case services:config(Type) of
        {ok, Services} ->
            start_services(Services);
        _ ->
            {error, services_cfg_undefined}
    end,
    case Result of
        ok ->
            ok;
        {error, Msg} ->
            ?INFO("系统启动失败，原因: ~w ~w.", [Type, Msg])
    end,
    {noreply, State};
handle_info(_Info, State) ->
    {noreply, State}.

terminate(_Reason, _State) ->
    ok.

code_change(_OldVsn, State, _Extra) ->
    {ok, State}.



%%----------------------------------------------------
%% 私有函数
%%----------------------------------------------------
start_services([]) -> ok;
start_services([{Id, Args} | T]) ->
    case services:get(Id) of
        {error, undefined} -> {error, {service_undefined, Id}};
        {ok, #service{id = Id, mfa = {M, F, A}, restart = Restart, type = Type}} ->
            case supervisor:start_child(server_sup, {Id, {M, F, A ++ Args}, Restart, 300000, Type, [Id]}) of
                {ok, _Pid} -> start_services(T);
                {error, Reason} -> {error, {Id, Reason}}
            end
    end.